package com.tgy.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;

@Component
public class RestTemplateUtil {

    @Resource
    private RestTemplate restTemplate;
    /**
     * 发送GET请求
     */
    public String GetData(String url, Map<String,String> param){
        // 请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return restTemplate.getForEntity(url,String.class,param).getBody();
    }

    /**
     * 发送POST-JSON请求
     * url地址接受参数中必须加@RequestBody注解
     */
    public String PostJsonData(String url, JSONObject param){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(param, headers);
        return restTemplate.postForEntity(url,requestEntity,String.class).getBody();
    }

    /**
     * 发送POST 表单请求
     * url地址接受参数中可以是对象接收，但是不能加@RequestBody注解
     */
    public String PostFormData(String url, MultiValueMap<String,String> param){
        // 请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return restTemplate.postForEntity(url,param,String.class).getBody();
    }

    /**
     * 发送Post时传入参数为Object
     */
    public String PostForObject(String url,Object obj){
        JSONObject param = JSON.parseObject(JSONObject.toJSONString(obj));
        return PostJsonData(url,param);
    }


    /**
     * 传入的为MultipartFile对象时：
     * 1.先将MultipartFile对象临时生成普通的File对象
     * 2.根据File对象的路劲生成FileSystemResource对象，再将FileSystemResource对象放入param进行传输
     * 3.将生成的File对象删除
     * @Param [jarFile, form]
     * @return java.lang.Object
     * @author: tianGuiYin
     * @date: 2021/11/25 10:11
     **/
    public String uploadFile(String url, MultipartFile jarFile,MultiValueMap<String,Object> param)throws Exception{
        HttpHeaders headers = new HttpHeaders();
        //生成临时文件(路劲根据自己修改)
        String tempFileName = UUID.randomUUID() + jarFile.getOriginalFilename().substring(jarFile.getOriginalFilename().lastIndexOf("."));
        String tempFilePath = "E:\\xlsfile\\" + tempFileName;
        File tempFile = new File(tempFilePath);
        jarFile.transferTo(tempFile);

        //封装传输参数且发送请求
        FileSystemResource fileSystemResource = new FileSystemResource(tempFilePath);
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);
        String cd = "filename=\"" + jarFile.getOriginalFilename() + "\"";
        headers.add("Content-Disposition", cd);
        param.add("file", fileSystemResource);
        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(param, headers);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, files, String.class);

        //删除临时文件
        try {
            tempFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseEntity.getBody();
    }

    /**
     * 使用restTemplate发送文件
     * @Param fileName      文件名称字符串，格式："filename=\"" + fileName + "\"";
     * @Param param         传输的参数，里面可以有多个，传输文件时此时里面包含一个FileSystemResource的文件对象
     * @return java.lang.String     调用接口返回的参数
     * @author: tianGuiYin
     * @date: 2021/11/25 8:36
     **/
    public String uploadFile(String url, String fileName, MultiValueMap<String,Object> param)throws Exception{
        HttpHeaders headers = new HttpHeaders();
        /*MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);*/
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.add("Content-Disposition", fileName);           //设置文件名称
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
        return responseEntity.getBody();
    }

    /**
     * 使用restTemplate发送文件。默认以当前文件名称传送
     * @Param param         传输的参数，里面可以有多个，传输文件时此时里面包含一个FileSystemResource的文件对象
     * @return java.lang.Object     调用接口返回的参数
     * @author: tianGuiYin
     * @date: 2021/11/25 8:36
     **/
    public String uploadFile(String url, MultiValueMap<String,Object> param)throws Exception{
        HttpHeaders headers = new HttpHeaders();
        /*MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);*/
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //添加文件
//        param.add("files", new FileSystemResource(filePath));
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
        return responseEntity.getBody();
    }

    /**
     * 使用RestTemplate发送一个文件流
     * parts中包含一个RestTemplateUtil.MultipartFileResource multipartFileResource = new RestTemplateUtil.MultipartFileResource(inputStream, fileName);对象就是文件
     * @Param []
     * @return java.lang.String
     * @author: tianGuiYin
     * @date: 2021/11/24 8:42
     **/
    public String senFile(String url,MultiValueMap<String,Object> parts) throws FileNotFoundException {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setBufferRequestBody(false);
        restTemplate.setRequestFactory(requestFactory);
        /*MultiValueMap<String,Object> parts = new LinkedMultiValueMap<>();
        File file = new File("E:\\xlsfile\\对方是否方式十分士大夫是打发打发十分防晒霜防晒发射点发生放松放松的Hass较大_2021_01_12_11_12_13.xlsx");
        InputStream inputStream = new FileInputStream(file);
        MultipartFileResource multipartFileResource = new MultipartFileResource(inputStream, "文件.xlsx");
        parts.add("file",multipartFileResource);
        parts.add("creatTime", "2021-01-01 01:01:01");
        parts.add("token", "12345");*/
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String,Object>> request = new HttpEntity<>(parts, headers);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, request, String.class);

        return exchange.getBody();
    }
    public static class MultipartFileResource extends InputStreamResource {
        private String filename;
        public MultipartFileResource(InputStream inputStream, String filename) {
            super(inputStream);
            this.filename = filename;
        }
        @Override
        public String getFilename() {
            return this.filename;
        }
        @Override
        public long contentLength() throws IOException {
            return -1; // we do not want to generally read the whole stream into memory ...
        }
    }


}
